<template>
  <div class="container">
    <div style="margin: 10px auto 30px; width: fit-content; font-size: 24px; color: #008c8c">《{{ listSongTitle }}》</div>

    <div class="search">
      <el-input v-model="params.name" placeholder="请输入歌曲名" clearable></el-input>
      <el-select v-model="params.singerId" placeholder="歌手" clearable>
        <el-option v-for="item in singerData" :key="item.id" :value="item.id" :label="item.name"></el-option>
      </el-select>
      <el-input v-model="params.other" placeholder="模糊查询" clearable></el-input>
      <el-button type="primary" @click="findBySearch">搜索</el-button>
      <el-button type="warning" @click="clearParams">清空</el-button>
      <el-button type="success" @click="addSong">添加歌曲</el-button>
    </div>

    <div class="table">
      <el-table ref="tableRef" :data="songData" stripe highlight-current-row style="width: 100%" height="68vh">
        <el-table-column fixed label="序号" prop="id" sortable width="80" align="center"></el-table-column>
        <el-table-column fixed label="歌手" prop="singerName" width="100" align="center">
          <template #default="{ row }">
            {{ row.singerName.split('-').length !== 1 ? row.singerName.split('-')[0] : row.singerName }}
          </template>
        </el-table-column>
        <el-table-column fixed label="歌曲名" prop="name" width="250" align="center">
          <template #default="{ row }">{{ row.name.split('-').length !== 1 ? row.name.split('-')[1] : row.name }}</template>
        </el-table-column>
        <el-table-column label="介绍" prop="introduction" width="130" align="center">
          <template #default="{ row }">
            <div class="multiline-ellipsis">{{ row.introduction }}</div>
          </template>
        </el-table-column>
        <el-table-column label="歌曲封面" prop="pic" width="100" align="center">
          <template #default="{ row }">
            <el-image
              style="width: 70px; height: 70px; border-radius: 50%"
              :src="'http://localhost:8080/api/files/' + row.pic"
              :preview-src-list="['http://localhost:8080/api/files/' + row.pic]"
            ></el-image>
          </template>
        </el-table-column>

        <el-table-column label="歌曲" prop="url" width="350" align="center">
          <template #default="{ row }">
            <div v-if="row.url != null && row.url !== ''">
              <audio v-if="row.url.includes('song|')" :src="'http://localhost:8080/api/files/' + row.url" controls></audio>
              <audio v-else :src="row.url" controls>
                <source :src="row.url" />
                您的浏览器不支持 audio 标签。
              </audio>
            </div>
            <div v-else>暂无歌曲</div>
          </template>
        </el-table-column>

        <el-table-column label="歌词" prop="lyric" width="150" align="center">
          <template #default="{ row }">
            <div class="multiline-ellipsis">
              {{ row.lyric }}
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="clicks" label="点击次数" width="130" sortable align="center"></el-table-column>
        <el-table-column prop="createTime" label="创建日期" width="150"></el-table-column>
        <el-table-column prop="updateTime" label="更新日期" width="150"></el-table-column>

        <el-table-column fixed="right" label="账号状态" prop="status" width="80">
          <template #default="{ row }">
            <el-switch v-model="row.sts" @change="updateStatus(row)"></el-switch>
          </template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" width="150" align="center">
          <template #default="{ row }">
            <div style="margin-bottom: 5px">
              <el-button type="primary" size="small" @click="editSong(row)">编辑</el-button>

              <el-dropdown trigger="hover" style="margin-left: 10px">
                <el-button type="success" size="small"> 下载 &nbsp;<i-ep-arrow-down /> </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item :disabled="!row.pic" @click="downLoadPic(row)">图片</el-dropdown-item>
                    <el-dropdown-item :disabled="!row.url" @click="downLoadUrl(row)">音频</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
            <div>
              <el-popconfirm
                title="你确定删除吗？"
                confirm-button-text="确定"
                cancel-button-text="取消"
                @confirm="deleteSong(row)"
              >
                <template #reference>
                  <el-button type="danger" size="small">删除</el-button>
                </template>
              </el-popconfirm>
              <el-dropdown trigger="hover" style="margin-left: 10px">
                <el-button type="info" size="small"> 详情 &nbsp;<i-ep-arrow-down /> </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item @click="detailBing(row)">Bing</el-dropdown-item>
                    <el-dropdown-item @click="detailMusic(row)">Music</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <div class="pagination">
      <el-pagination
        v-model:current-page="params.pageNum"
        v-model:page-size="params.pageSize"
        :page-sizes="[5, 10, 15, 20]"
        size="default"
        layout="total, sizes, prev, pager, next, jumper"
        :total="params.total"
        @size-change="findBySearch"
        @current-change="findBySearch"
      />
    </div>

    <div class="dialog">
      <!-- 添加歌曲 -->
      <el-dialog v-model="addDialogVisible" width="40%" align-center>
        <template #header>
          <h3 style="text-align: center; font-weight: 400">选择添加的歌曲</h3>
        </template>
        <el-form :model="addSongForm">
          <el-form-item label="搜索歌曲" label-width="20%">
            <el-input v-model="addSongForm.name" placeholder="请输入歌曲名" clearable></el-input>
          </el-form-item>
          <el-form-item label-width="20%">
            <el-select v-model="addSongForm.singerId" placeholder="歌手" clearable>
              <el-option v-for="item in singerAllData" :key="item.id" :label="item.name" :value="item.id"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label-width="20%">
            <el-input v-model="addSongForm.other" placeholder="模糊查询" clearable></el-input>
          </el-form-item>
          <el-form-item label="歌曲" label-width="20%">
            <el-select v-model="addSongForm.songId" placeholder="请选择" clearable style="width: 48%; margin-right: 4%">
              <el-option v-for="item in addSomeData.songList" :key="item.id" :label="item.name" :value="item.id"></el-option>
            </el-select>
            <div style="width: 28%">检索到：{{ addSomeData.total }}首歌曲</div>
          </el-form-item>
          <el-form-item label-width="20%">
            <el-button color="#008c8c" @click="addAll">添加全部检索内容进歌单</el-button>
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="addDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="addSubmit">确定</el-button>
          </div>
        </template>
      </el-dialog>
      <!-- 编辑歌曲 -->
      <el-dialog v-model="editDialogVisible" width="50%" top="3vh" align="center" @close="cancel">
        <template #header>
          <h3 style="text-align: center; font-weight: 400">编辑歌曲</h3>
        </template>
        <el-form :model="editSongForm">
          <el-form-item label="歌曲名" label-width="20%">
            <el-input v-model="editSongForm.name" clearable></el-input>
          </el-form-item>
          <el-form-item label="歌手" label-width="20%">
            <el-select v-model="editSongForm.singerId" placeholder="请选择">
              <el-option v-for="item in singerData" :key="item.id" :label="item.name" :value="item.id"></el-option>
            </el-select>
          </el-form-item>

          <!-- 头像上传 -->
          <el-form-item label="歌曲封面" label-width="20%">
            <el-upload
              action="http://localhost:8080/api/files/upload?fileDir=songPic"
              list-type="picture-card"
              :auto-upload="true"
              :limit="1"
              :on-success="successUpload"
              :on-remove="handleRemove"
              :on-preview="handlePicturePreview"
              :file-list="picList"
              :class="{ 'none-up': uploadDisabled }"
            >
              <i-ep-plus />
            </el-upload>
          </el-form-item>

          <el-form-item label="歌曲" label-width="20%" style="position: relative">
            <el-upload
              action="http://localhost:8080/api/files/upload?fileDir=song"
              list-type="stringtext"
              :on-success="successSongUpload"
              :on-remove="handleSongRemove"
              :file-list="songList"
              :limit="1"
              :on-exceed="handleSongExceed"
              style="width: 90%"
            >
              <el-button type="primary" style="position: absolute; left: 5%; top: -2%">点击上传</el-button>
            </el-upload>
            <div style="position: absolute; left: 30%; top: -3%">
              <el-button type="warning" :disabled="songList.length !== 0" @click="songUrlVisible = true">上传网络地址</el-button>
              <el-button type="info" style="margin-left: 50px" @click="((songList = []), (editSongForm.url = ''))"
                >清空</el-button
              >
            </div>
          </el-form-item>

          <el-form-item label="介绍" label-width="20%">
            <el-input v-model="editSongForm.introduction" style="width: 90%" type="textarea" rows="3"></el-input>
          </el-form-item>
          <el-form-item label="歌词" label-width="20%">
            <el-input v-model="editSongForm.lyric" style="width: 90%" type="textarea" rows="5"></el-input>
          </el-form-item>
          <el-form-item prop="clicks" label="点击次数" label-width="20%">
            <el-input v-model="editSongForm.clicks" style="width: 90%" clearable></el-input>
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="cancel">取消</el-button>
            <el-button type="primary" @click="submit"> 确定 </el-button>
          </div>
        </template>
      </el-dialog>
      <!-- 头像预览弹窗 -->
      <el-dialog v-model="preImgVisible" width="600" align-center>
        <img :src="'http://localhost:8080/api/files/' + editSongForm.pic" alt="头像预览" style="width: 100%" />
      </el-dialog>
      <!-- 歌曲网络地址弹窗 -->
      <el-dialog v-model="songUrlVisible" width="500" title="输入歌曲的网络地址" align-center @close="editSongForm.url = ''">
        <el-input v-model="editSongForm.url"></el-input>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="((songUrlVisible = false), (editSongForm.url = ''))">取消</el-button>
            <el-button
              type="primary"
              @click="((songList = editSongForm.url ? [{ name: editSongForm.url }] : []), (songUrlVisible = false))"
              >确定</el-button
            >
          </div>
        </template>
      </el-dialog>
    </div>
  </div>
</template>

<script setup lang="ts" name="songList2Song">
import { listSongDeleteApi, listSongSaveApi } from '@/api/listSong'
import { singerFindAllApi } from '@/api/singer'
import { songFindAllApi, songFindBySearchApi, songSaveApi } from '@/api/song'
import { songListFindBySongListIdApi } from '@/api/songList'
import { ElMessage, ElMessageBox } from 'element-plus'
import { onActivated, onMounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'

// 路由获取路径参数
const route = useRoute()
// 路由器
const router = useRouter()

// 封面上传动态类
const uploadDisabled = ref(false)

// 添加弹窗
const addDialogVisible = ref(false)
// 编辑弹窗
const editDialogVisible = ref(false)
// 预览弹窗
const preImgVisible = ref(false)
// 歌曲网络地址弹窗
const songUrlVisible = ref(false)

// 添加歌曲表单数据
const addSongForm: any = ref({
  name: null,
  singerId: null,
  other: null,
  songId: null,
  pageNum: 1,
  pageSize: 50,
  // total: '',
  // songList: []
})
// TODO:尽量让请求里的参数别掺和进一些其他不必要的变量，否则容易导致一些怪异的错误异常
// 添加歌曲表单分离出来的数据
const addSomeData: any = ref({
  total: '',
  songList: [],
})
// 编辑歌曲表单数据
const editSongForm = ref({
  id: '',
  name: '',
  singerId: '',
  pic: '',
  url: '',
  introduction: '',
  lyric: '',
  clicks: '',
  cont: 0, //要防止后续清数据时候丢失
})
// 页面数据
const params: any = ref({
  id: '',
  name: '',
  singerId: '',
  other: '',
  songListId: '',
  pageNum: 1,
  pageSize: 5,
  total: '',
})
// 歌曲文件列表
const songList: any = ref([])
// 封面文件列表
const picList: any = ref([])

// 歌曲数据
const songData = ref()
// 歌手数据
const singerData: any = ref([])
// 所有歌手数据
const singerAllData: any = ref([])
// 全部歌曲
const songsList: any = ref([])

// 歌单title
const listSongTitle = ref()
// 歌单id
params.value.songListId = route.query.songListId

onMounted(async () => {
  // console.log('组件首次挂载');
  if (!params.value.songListId) {
    ElMessage.warning('请先选择歌单')
    router.push({
      path: '/songList',
    })
  }
  // 发送请求获取歌曲数据
  findBySearch()
  // 发送请求获取歌手数据
  findSingerData()
  // 所有歌手信息
  findSingerAll()
  // 所有歌曲信息
  fingSongAll()
  // 歌单信息
  findSongList()
})
onActivated(() => {
  // console.log('组件被重新激活');
  if (route.query.songListId && route.query.songListId !== params.value.songListId) {
    // 清空一下歌手信息
    singerData.value = []
    params.value.songListId = route.query.songListId
    findBySearch()
    findSingerData()
    findSongList()
  }
})

// 根据歌单id查询歌曲数据
const findBySearch = async () => {
  let res = await songFindBySearchApi(params.value)
  songData.value = res.data.list.map((item: any) => ({
    ...item,
    sts: item.status === '0',
  }))
  params.value.total = res.data.total
}
// 根据歌单id查询歌单信息
const findSongList = async () => {
  let res = await songListFindBySongListIdApi(params.value.songListId)
  listSongTitle.value = res.data.title
}
// 查询该歌单里的所有歌手信息
const findSingerData = async () => {
  params.value.pageSize = 25 //取一个较大的值，确保能够取完
  let res = await songFindBySearchApi(params.value)
  singerData.value = res.data.list.map((item: any) => ({
    name: (item.name = item.name.split('-').length >= 2 ? item.name.split('-')[0] : item.name),
    id: item.singerId,
  }))
  // 去重操作
  // singerData.value = [...new Set(singerData.value)]针对普通数组
  singerData.value = Array.from(new Map(singerData.value.map((item: any) => [item.name, item])).values())
  // 重新将pageSize重置回原先的值
  params.value.pageSize = 5
}
// 查询所有歌手信息
const findSingerAll = async () => {
  let res = await singerFindAllApi()
  singerAllData.value = res.data
}
// 查询所有歌曲信息
const fingSongAll = async () => {
  let res = await songFindAllApi()
  songsList.value = res.data
}
// 清空
const clearParams = () => {
  // params.value = {
  //   id: '',
  //   name: '',
  //   singerId: '',
  //   other: '',
  //   songListId: '',
  //   pageNum: 1,
  //   pageSize: 5,
  //   total: ''
  // }
  // 上述的清空方式会把params.value.songListId变为undefined
  params.value.name = ''
  params.value.singerId = ''
  params.value.other = ''
  console.log('清空：', params.value.songListId)
  findBySearch()
}
// 更改账号状态
const updateStatus = async (row: any) => {
  row.status = row.status === '0' ? '1' : '0'
  await songSaveApi(row, 0)
  ElMessage.success('修改账号状态成功')
  findBySearch()
}
// 添加歌曲
const addSong = () => {
  addDialogVisible.value = true
}
// 编辑歌曲
const editSong = (row: any) => {
  picList.value = []
  songList.value = []
  editDialogVisible.value = true
  // editSongForm.value = row
  Object.assign(editSongForm.value, row)
  if (row.pic) {
    picList.value.push({ name: row.pic, url: 'http://localhost:8080/api/files/' + row.pic })
  }
  if (row.url) {
    console.log('row.url:', row.url)
    songList.value.push({ name: row.url, url: 'http://localhost:8080/api/files/' + row.url })
  }
  uploadDisabled.value = picList.value.length >= 1
}
// 头像上传成功
const successUpload = (res: any, file: any, fileList: any) => {
  picList.value = fileList
  uploadDisabled.value = picList.value.length >= 1
  editSongForm.value.pic = res.data
}
// 歌曲上传成功
const successSongUpload = (res: any, file: any, fileList: any) => {
  songList.value = fileList
  editSongForm.value.url = res.data
}
// 歌曲上传超过limit时覆盖掉前一个
const handleSongExceed = (files: File[]) => {
  songList.value = files
  // console.log(files)   files:是超过limit之后上传的文件数组【一个或多个，这里是一个】
}
// 删除头像
const handleRemove = (file: any, fileList: any) => {
  let index = picList.value.findIndex((item: any) => {
    return item.uid === file.uid
  })
  picList.value.splice(index, 1)
  uploadDisabled.value = picList.value.length >= 1
  editSongForm.value.pic = ''
}
// 删除歌曲
const handleSongRemove = (file: any, fileList: any) => {
  let index = songList.value.findIndex((item: any) => {
    return item.uid === file.uid
  })
  songList.value.splice(index, 1)
  editSongForm.value.url = ''
}
// 预览头像
const handlePicturePreview = (file: any) => {
  // console.log('file', file)
  preImgVisible.value = true
}
// 取消编辑歌曲
const cancel = () => {
  editDialogVisible.value = false
  picList.value = []
  songList.value = []
}
// 确定编辑歌曲
const submit = async () => {
  await songSaveApi(editSongForm.value, editSongForm.value.cont)
  ElMessage.success('修改成功')
  editDialogVisible.value = false
  findBySearch()
}
// 确定添加歌曲
const addSubmit = async () => {
  const ids = {
    songListId: params.value.songListId,
    songId: addSongForm.value.songId,
  }
  await listSongSaveApi(ids)
  ElMessage.success('添加成功')
  addDialogVisible.value = false
  findBySearch()
}
// 删除
const deleteSong = async (row: any) => {
  await listSongDeleteApi(row.id, params.value.songListId)
  findBySearch()
  ElMessage.success('删除成功')
}
// 下载图片
const downLoadPic = (row: any) => {
  if (row.pic.includes('|')) {
    location.href = 'http://localhost:8080/api/files/' + row.pic
  } else {
    ElMessage.warning('无可下载资源')
  }
}
// 下载音频
const downLoadUrl = (row: any) => {
  if (row.url.includes('|')) {
    location.href = 'http://localhost:8080/api/files/' + row.url
  } else if (row.url.includes('http')) {
    location.href = row.url
  } else {
    ElMessage.warning('无可下载资源')
  }
}
// 网页bing详情
const detailBing = (row: any) => {
  window.open('https://cn.bing.com/search?q=' + row.name, '_blank')
}
// 前台Music详情【TODO】
const detailMusic = (row: any) => {
  // window.open('http://localhost:163/?name='+row.name+'&type=netease','_blank')
  ElMessage.warning('该功能还未开发，敬请期待')
}
// 添加全部检索内容进歌单
const addAll = async () => {
  addSomeData.value.songList.forEach(async (item: any) => {
    let ids = {
      songListId: params.value.songListId,
      songId: item.id,
    }
    await listSongSaveApi(ids)
  })
  ElMessage.success('全部添加成功')
  findBySearch()
  addDialogVisible.value = false
}
watch(
  [() => addSongForm.value.name, () => addSongForm.value.other, () => addSongForm.value.singerId],
  async (newValue, oldValue) => {
    let res = await songFindBySearchApi(addSongForm.value)
    addSomeData.value.total = res.data.total
    addSomeData.value.songList = res.data.list
    console.log('songList:', addSomeData.value.songList)

    //   let res:any = songFindAllApi(addSongForm.value)
    //   addSongForm.value.total = res.data.length
    //   addSongForm.value.songList = res.data
    //   console.log('songList:', addSongForm.value.songList)
  },
  { deep: true }
)
watch(addDialogVisible, (newValue, oldValue) => {
  // 清理数据
  // addSongForm.value.songList = songsList.value
  // addSongForm.value.total = songsList.value.length
  addSongForm.value = {
    name: null,
    singerId: null,
    other: null,
    songId: null,
    pageNum: 1,
    pageSize: 50,
  }
  addSomeData.value.songList = songsList.value
  addSomeData.value.total = songsList.value.length
})
</script>

<style scoped lang="scss">
.container {
  .search {
    display: flex;
    flex-wrap: nowrap;

    .el-input {
      width: 200px;
      margin-right: 10px;
    }

    .el-select {
      width: 100px;
      margin-right: 10px;
    }
  }

  .table {
    margin: 15px 0;

    .el-switch {
      --el-switch-on-color: #13ce66;
      --el-switch-off-color: #ff4949;
    }

    // 限制歌词的显示格式
    .multiline-ellipsis {
      display: -webkit-box;
      /* 多行折叠支持 */
      -webkit-line-clamp: 1;
      /* 限制显示的行数 */
      -webkit-box-orient: vertical;
      /* 垂直排列子元素（多行） */
      overflow: hidden;
      /* 超出隐藏 */
      text-overflow: ellipsis;
      /* 超出用省略号 */
      line-height: 20px;
      /* 每行高度（可调） */
      max-height: 60px;
      /* 3行 * line-height */
    }
  }

  .pagination {
    display: flex;
    justify-content: center;
  }

  .dialog {
    .el-input,
    .el-select {
      width: 80%;
    }
  }
}

/* CSS */
.cell {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

// 深度选择器
.none-up ::v-deep(.el-upload--picture-card) {
  display: none;
}
</style>
